package com.alibaba.citrus.ots.price.ability.functions.factory.activity.process;

import com.alibaba.citrus.common.Result;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.price.ability.functions.GiftTypeEnum;
import com.alibaba.citrus.ots.price.ability.functions.constant.ReUsableEnum;
import com.alibaba.citrus.ots.price.ability.functions.entity.activity.ActivityTermEntity;
import com.alibaba.citrus.ots.price.ability.functions.entity.activity.ActivityTitleEntity;
import com.alibaba.citrus.ots.price.ability.functions.entity.activity.SegmentedActivityTermEntity;
import com.alibaba.citrus.ots.price.ability.functions.factory.activity.SegmentedActivityTermFactory;
import com.alibaba.citrus.ots.price.repository.ActivityQueryRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.epoch.app.otspricecenter.dto.request.ActivityInfoRequest;
import com.epoch.app.otspricecenter.dto.request.ActivityItemInfo;
import com.epoch.app.otspricecenter.dto.request.ActivityItemInfoRequest;
import com.epoch.app.otspricecenter.dto.request.ParticipateActivityInfoRequest;
import com.epoch.app.otspricecenter.dto.request.ParticipateActivityTermRequest;
import com.epoch.app.otspricecenter.dto.response.ActivityTermResponse;
import com.epoch.app.otspricecenter.model.enums.ActivityTypeEnum;
import com.epoch.app.otspricecenter.sdo.ActivityTermSDO;
import com.epoch.app.otspricecenter.sdo.ActivityTitleExtSDO;
import com.epoch.app.otspricecenter.sdo.ActivityTitleSDO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: qiaojiange
 * @create: 2021/11/17
 * @Description 买赠、搭赠活动明细处理器
 */
@Component
public class BuyGiftActivityProcessor extends ActivityProcess {
    @Resource
    private ActivityQueryRepository queryRepository;

    private static Log log = Log.getLogger(BuyGiftActivityProcessor.class);

    private static Integer ZERO = 0;

    @Override
    public List<ActivityTermEntity> addInfo(ActivityTitleEntity titleEntity,
                                            String itemId) {
        Set<ActivityTermSDO> activityTermSDOS = queryRepository.queryTermSDOList(titleEntity.obtainActivityId());

        List<ActivityTermEntity> result = new ArrayList<>();

        for (ActivityTermSDO sdo : activityTermSDOS) {
            ActivityTermEntity termEntity = ActivityTermEntity.of(sdo);
//        原品编号没有填，需要在 A表 （活动项目和货品关系表）找原品列表：
            if (StringUtils.isBlank(termEntity.obtainItemId())) {
                List<String> itemIdList = queryRepository.queryTermAndItemRelationByTermId(
                        titleEntity.obtainActivityId(), termEntity.obtainActivityTermId());
                termEntity.setItemList(itemIdList);
            }

            //原品 ID 或者原品清单列表不是空的，但是没有包含该原品 ID，直接过滤掉
            if (termEntity.itemIdOrItemIdListIsNotNull()
                    && !termEntity.containItemId(itemId)) {
                continue;
            }

//          没有原品数量，需要查坎级表；
            if (ZERO.equals(termEntity.obtainItemQuantity())) {
                List<SegmentedActivityTermEntity> segmentedActivityTermEntityList =
                        SegmentedActivityTermFactory.create(titleEntity.obtainActivityId(), termEntity.obtainActivityTermId());

                termEntity.setSegmentedActivityTermEntityList(segmentedActivityTermEntityList);
            }

            //没有赠品编号，查询赠品表 D;
            if (Objects.isNull(termEntity.obtainGiftId())) {
                List<String> giftIdList = queryRepository.queryTermAndGiftRelationList(titleEntity.obtainActivityId(),
                        termEntity.obtainActivityTermId());
                termEntity.setGiftIdList(giftIdList);
            }


            result.add(termEntity);
        }
        return result;
    }

    @Override
    public String getActivityTypeDesc() {
        return ActivityTypeEnum.BUY_GIFT.getValue();
    }

    @Override
    @ProcessInvoker(printLog = true)
    public List<ActivityItemInfo> processGift(ActivityTermEntity activityTermEntity, ActivityInfoRequest request) {
//        1. 原品 ID为空，返回原品清单，返回赠品
//            a. 赠品 ID 为空，查赠品表
//            b. 赠品 ID 不为空，直接返回

//        2. 原品 ID 不为空，直接返回赠品，
//            a. 赠品 ID 为空，查赠品表
//            b. 赠品 ID 不为空，直接返回

//        3. 原品数量不为空，
//            a.赠品 ID 为空，查询赠品表
//            b.赠品 ID 不为空，直接返回
        List<ActivityItemInfo> result = new ArrayList<>();
        try {
            ActivityItemInfoRequest infoRequest = request.getItemList().get(0);
            if (activityTermEntity.containItemId(infoRequest.getItemId())
                    && Objects.nonNull(activityTermEntity.obtainItemQuantity())
                    && infoRequest.getItemQuantity().intValue() >= activityTermEntity.obtainItemQuantity()) {

                if (StringUtils.isNotBlank(activityTermEntity.obtainGiftId())) {
                    addGiftInfo(activityTermEntity, result, infoRequest, activityTermEntity.obtainGiftId());
                    activityTermEntity.setGiftActivityType(GiftTypeEnum.ONE_GIFT.getCode());
                }

                if (CollectionUtils.isNotEmpty(activityTermEntity.getGiftIdList())) {
                    for (String giftId : activityTermEntity.getGiftIdList()) {
                        addGiftInfo(activityTermEntity, result, infoRequest, giftId);
                        activityTermEntity.setGiftActivityType(GiftTypeEnum.MULTIPLY_GIFT.getCode());
                    }
                }
                return result;
            }


//        4. 原品 id不为空，原品数量为空，查找坎级赠品表，获取赠品信息，按照门槛进行匹配，坎级是否复用
            List<SegmentedActivityTermEntity> segmentedActivityTermEntityList = activityTermEntity.getSegmentedActivityTermEntityList();
            if (activityTermEntity.containItemId(infoRequest.getItemId()) &&
                    ZERO.equals(activityTermEntity.obtainItemQuantity())
                    && CollectionUtils.isNotEmpty(segmentedActivityTermEntityList)) {

//            4.1 单坎级循环复用的逻辑
                if (segmentedActivityTermEntityList.size() == 1) {
                    singleSegmentedReUse(result, infoRequest, segmentedActivityTermEntityList);
                    return result;
                }

//           4.2 下面是坎级的其他情况
                //降序排列
                segmentedActivityTermEntityList.sort((o1, o2) -> {
                    return o1.obtainItemQuantity() <= o2.obtainItemQuantity() ? 1 : -1;
                });

                //传入的原品数量
                Long userInputItemQuantity = new Long(infoRequest.getItemQuantity());

                boolean[] haveMatch = new boolean[1];
                haveMatch[0] = false;

                for (SegmentedActivityTermEntity seg : segmentedActivityTermEntityList) {
//              第一次匹配不用区分是否有坎级复用标识
                    if (!haveMatch[0]) {
                        userInputItemQuantity = doSegmentedActivityMatch(result, userInputItemQuantity, seg, haveMatch);
                        if (haveMatch[0]) {
                            continue;
                        }
                    }

//              第一次匹配之后，后面的进行匹配都是要用坎级复用标识进行匹配的，如果有坎级不复用标识，则不进行匹配；
                    if (haveMatch[0] && !ReUsableEnum.NO_REUSABLE.getValue().equals(seg.obtainWithSendNotReUsable())) {
                        userInputItemQuantity = doSegmentedActivityMatch(result, userInputItemQuantity, seg, haveMatch);
                    }
                }
                //坎级赠品
                activityTermEntity.setGiftActivityType(GiftTypeEnum.SEGMENTED_GIFT.getCode());
            }
        } catch (Exception e) {
            log.error("BuyGiftActivityProcessor#processGift_fail");
            log.error("处理搭赠出了异常，该活动项目不被命中，活动termId=" + activityTermEntity.obtainActivityTermId(), e);
        }
        return result;
    }

    /**
     * 单坎级循环使用逻辑
     *
     * @param result                          返回结果
     * @param infoRequest                     活动请求
     * @param segmentedActivityTermEntityList 坎级活动列表
     */
    private void singleSegmentedReUse(List<ActivityItemInfo> result, ActivityItemInfoRequest infoRequest,
                                      List<SegmentedActivityTermEntity> segmentedActivityTermEntityList) {
        SegmentedActivityTermEntity entity = segmentedActivityTermEntityList.get(0);
        if (Objects.nonNull(entity.obtainItemQuantity())
                && infoRequest.getItemQuantity() >= entity.obtainItemQuantity()) {

            ActivityItemInfo giftInfo = new ActivityItemInfo();
            giftInfo.setItemId(entity.obtainGiftId());

            Long multiple = infoRequest.getItemQuantity() / entity.obtainItemQuantity();
            Long giftQuantity = multiple * entity.obtainGiftQuantity();
            giftInfo.setItemQuantity(giftQuantity.intValue());

            giftInfo.setSalesUnit(entity.obtainSalesUnit());
            result.add(giftInfo);
        }
    }

    /**
     * 添加赠品信息
     *
     * @param activityTermEntity term 实体
     * @param result             赠品列表
     * @param infoRequest        用户输入信息
     * @param giftId
     */
    private void addGiftInfo(ActivityTermEntity activityTermEntity, List<ActivityItemInfo> result,
                             ActivityItemInfoRequest infoRequest, String giftId) {
        ActivityItemInfo giftInfo = new ActivityItemInfo();
        giftInfo.setItemId(giftId);
        //倍数，计算整数倍
        Integer multiply = infoRequest.getItemQuantity().intValue() / activityTermEntity.obtainItemQuantity();
        if (Objects.nonNull(activityTermEntity.obtainGiftQuantity())) {
            giftInfo.setItemQuantity(multiply * activityTermEntity.obtainGiftQuantity());
            giftInfo.setSalesUnit(activityTermEntity.obtainSalesUnit());
            result.add(giftInfo);
        } else {
            log.error("搭赠活动，当前activityTermEntity中赠品数量为空！activityTermEntity={}", activityTermEntity);
        }
    }

    /**
     * 做坎级活动匹配
     *
     * @param list                  要返回的赠品列表
     * @param userInputItemQuantity 用户输入商品数量
     * @param seg                   坎级活动实体
     * @param haveMatch
     * @return 没有匹配的用户剩余数量
     */
    @NotNull
    private Long doSegmentedActivityMatch(List<ActivityItemInfo> list, Long userInputItemQuantity,
                                          SegmentedActivityTermEntity seg, boolean[] haveMatch) {
        //用户输入原品数量大于等于坎级原品数量
        if (userInputItemQuantity >= seg.obtainItemQuantity()) {
            ActivityItemInfo itemInfo = ActivityItemInfo.builder().itemId(seg.obtainGiftId())
                    .itemQuantity(seg.obtainGiftQuantity().intValue()).salesUnit(seg.obtainSalesUnit()).build();
            list.add(itemInfo);
            userInputItemQuantity -= seg.obtainItemQuantity();
            //匹配成功
            haveMatch[0] = true;
        }
        return userInputItemQuantity;
    }

    /**
     * 处理特价，对买赠和搭赠无用
     *
     * @param activityTermEntity
     * @param request
     * @return
     */
    @Override
    public String processSpecialOfferPrice(ActivityTermEntity activityTermEntity, ActivityInfoRequest request) {
        return null;
    }

    @Override
    @ProcessInvoker(printLog = true)
    public Long calculatePreOccupyFee(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest) {
        List<ActivityItemInfo> giftList = termRequest.getGiftList();
        long thisPreOccupyFee = 0L;
        if (CollectionUtils.isNotEmpty(giftList)) {
            //本次预占用费用=赠品常规价*赠品数量
            for (ActivityItemInfo gift : giftList) {
                thisPreOccupyFee += gift.getItemPrice() * gift.getItemQuantity();
            }
        }

        return thisPreOccupyFee;
    }

    @Override
    public Integer calculateOccupyQuantity(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest) {
        //活动占用量=原品数量
        return termRequest.getItem().getItemQuantity();
    }

    @Override
    public Boolean filterTermOfCreate(ActivityTermEntity termEntity, String itemId) {
        return termEntity.containItemId(itemId);
    }

    @Override
    @ProcessInvoker(printLog = true)
    public Result<Boolean> checkParticipateActivityData(ParticipateActivityInfoRequest request, ActivityTermResponse response) {

        //校验赠品信息
        Map<String, ActivityItemInfo> giftMapRequest = request.getParticipateActivityTermRequest().
                getGiftList().stream().collect(Collectors.toMap(e -> e.getItemId(), Function.identity()));
        Map<String, ActivityItemInfo> giftMapResponse = response.getGiftList()
                .stream().collect(Collectors.toMap(e -> e.getItemId(), Function.identity()));

        for (String e : giftMapRequest.keySet()) {
            ActivityItemInfo giftResponse = giftMapResponse.get(e);
            if (Objects.isNull(giftResponse)) {
                log.error("参加活动失败，当前活动的赠品列表不包含用户传入赠品! 当前活动赠品列表={}, 用户传入赠品id={}", response.getGiftList(), e);
                return Result.failure("参加活动失败，当前活动的赠品列表不包含用户传入赠品! 当前活动赠品列表="+response.getGiftList()+", 用户传入赠品id="+ JSON.toJSONString(e));
            }
        }

        return Result.success(Boolean.TRUE);
    }

    @Override
    public Boolean checkPreOccupyQuantity(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest, Integer preOccupyQuantity) {
        if (preOccupyQuantity <= 0) {
            log.error("活动数量已经占用完了，该货品占用活动失败！活动申请活动量:{}, 已经占用的活动量:{},剩余活动量:{},本次预占成功活动量：{},客户当前需要占用的活动量:{}",
                    termEntity.obtainApplyItemQuantity(), termEntity.obtainActivityOccupyQuantity(), termEntity.obtainActivityRemainingQuantity(),
                    preOccupyQuantity, termRequest.getItem().getItemQuantity());
            return false;
        }
        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            return false;
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                return false;
            }

            //活动占用量校验
            Long newActivityOccupyItemQuantity = activityTitleExtSDO.getActivityOccupyQuantity() + preOccupyQuantity;
            if (activityTitleExtSDO.getApplyItemQuantity() < newActivityOccupyItemQuantity) {
                log.error("活动数量已经占用完了，该货品占用活动失败！活动申请活动量:{}, 已经占用的活动量:{},本次预占数量={},用户占用的活动量:{}",
                        activityTitleExtSDO.getApplyItemQuantity(), activityTitleExtSDO.getActivityOccupyQuantity(), preOccupyQuantity,
                        termRequest.getItem().getItemQuantity());
                return false;
            }
        } else {
            Integer newActivityOccupyItemQuantity = termEntity.obtainActivityOccupyQuantity() + preOccupyQuantity;
            if (termEntity.obtainApplyItemQuantity() < newActivityOccupyItemQuantity) {
                log.error("当前剩余活动数量无法满足本次活动请求，该货品占用活动失败！活动申请活动量:{}, 已经占用的活动量:{},剩余活动量:{},本次要占用的活动量:{}",
                        termEntity.obtainApplyItemQuantity(), termEntity.obtainActivityOccupyQuantity(), termEntity.obtainActivityRemainingQuantity(),
                        termRequest.getItem().getItemQuantity());
                return false;
            }
        }

        return true;
    }

    @Override
    public Boolean checkPreOccupyFee(ActivityTermEntity termEntity, Long thisPreOccupyFee) {
        if (thisPreOccupyFee == 0L) {
            log.error("活动占用费用失败！预占金额为0的情况，活动申请费用:{},活动已占用费用:{},活动剩余费用:{},本次申请费用:{}，活动termId={}",
                    termEntity.obtainApplyFee(), termEntity.obtainActivityOccupyFee(), termEntity.obtainActivityRemainingFee(),
                    thisPreOccupyFee, termEntity.obtainActivityTermId());
            return false;
        }

        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            return false;
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                return false;
            }

            //活动占用费用校验
            Long newActivityOccupyFee = activityTitleExtSDO.getActivityOccupyFee() + thisPreOccupyFee;
            if (activityTitleExtSDO.getApplyFee() < newActivityOccupyFee) {
                log.error("活动占用费用失败！活动申请费用:{},活动已占用费用:{},活动剩余费用:{}, 本次申请费用:{}",
                        activityTitleExtSDO.getApplyFee(), activityTitleExtSDO.getActivityOccupyFee(),
                        activityTitleExtSDO.getApplyFee() - activityTitleExtSDO.getActivityOccupyFee(), thisPreOccupyFee);
                return false;
            }
        } else {
            long activityOccupyFee = termEntity.obtainActivityOccupyFee() + thisPreOccupyFee;
            if (termEntity.obtainApplyFee() < activityOccupyFee) {
                log.error("活动占用费用失败！活动申请费用:{},活动已占用费用:{},活动剩余费用:{}, 本次申请费用:{}",
                        termEntity.obtainApplyFee(), termEntity.obtainActivityOccupyFee(), termEntity.obtainActivityRemainingFee(),
                        thisPreOccupyFee);
                return false;
            }
        }


        return true;
    }
}
